# -*- coding: utf-8 -*-
from openerp.osv import fields
from openerp.osv import osv
from openerp import tools
from openerp.http import request as request_all
from openerp import SUPERUSER_ID
import StringIO
import xlwt, json
import base64
import datetime
from openerp.addons.web.http import request
ISODATEFORMAT = '%Y-%m-%d'
ISODATETIMEFORMAT = '%Y-%m-%d %H-%M-%S'


class partner_requirement_type(osv.osv):
    # 对应的设置菜单在销售的设置里面
    _name = "partner.requirement.type"
    _columns = {
        'name': fields.char('客户需求类型维护', required=True),
    }


class res_partner(osv.osv):
    _inherit = "res.partner"

    def create(self, cr, uid, vals, context=None):
        if vals.get('customer') and vals.get('is_company'):
            partner_id = self.search(cr, uid, [('name', '=', vals.get('name')), ('is_company', '=', True), ('customer', '=', True)], context=context)
            if partner_id:
                raise osv.except_osv(u'错误!', u'相同的客户名称已经存在!')
        if vals.get('name') and vals.get('supplier'):
            partner_row = self.search(cr, uid, [('name', '=', vals.get('name')), ('supplier', '=', True)], context=context)
            if partner_row:
                raise osv.except_osv(u'错误!', u'供应商有重名!')
        return super(res_partner, self).create(cr, uid, vals, context=context)

    def onchange_principal(self, cr, uid, ids, principal, context=None):
        context = context or {}
        if principal:
            for partner in self.browse(cr, uid, ids, context=context):
                for multi_address in partner.multi_address_ids:
                    if multi_address.id == principal:
                        self.pool.get('customer.address').write(cr, uid, principal, {'default': True}, context=context)
                    else:
                        self.pool.get('customer.address').write(cr, uid, multi_address.id, {'default': False}, context=context)
        return True

    def _compute_customer_fee(self, cr, uid, ids, name, arg, context=None):
        res = {}
        for partner_obj in self.browse(cr, uid, ids, context=context):
            voucher_ids = self.pool.get("account.voucher").search(
                cr, SUPERUSER_ID, [('partner_id', '=', partner_obj.id)], context=context)
            if voucher_ids:
                res[partner_obj.id] = sum([voucher_obj.amount for voucher_obj in self.pool.get(
                    'account.voucher').browse(cr, SUPERUSER_ID, voucher_ids, context=context)])
            else:
                res[partner_obj.id] = 0
        return res

    def _get_office_invoice_fee(self, cr, uid, ids, name, arg, context=None):
        res = {}
        for partner_obj in self.browse(cr, uid, ids, context=context):
            invoice_id = self.pool.get('official.invoice').search(cr, uid, [('partner_id', '=', partner_obj.id)], context=context)
            invoice_num = 0
            for invoice_obj in self.pool.get('official.invoice').browse(cr, uid, invoice_id, context=context):
                invoice_num = invoice_num + invoice_obj.sale_order_amount_total
            res[partner_obj.id] = invoice_num
        return res

    def write(self, cr, uid, ids, vals, context=None):
        user_objs = self.pool.get('res.users').browse(cr, uid, uid, context=context)
        if vals.get('cust_grade', False) == u'中断客户':
            vals.update({'active': False})
        for partner in self.browse(cr, uid, ids, context=context):
            if partner.user_ids and uid not in [user.id for user in partner.user_ids] and (not user_objs.has_group('account.group_account_user') and not user_objs.has_group('base.group_hr_user')):
                raise osv.except_osv(u'错误!', u'不能修改其他用户的信息')
            if partner.user_ids and not vals.get('mobile', 'default_vals'):
                raise osv.except_osv(u'错误!', u'手机号码不为空!')
            if vals.get('name') and (vals.get('supplier') or partner.supplier):
                partner_row = self.search(cr, uid, [('name', '=', vals.get('name')), ('supplier', '=', True)], context=context)
                if partner_row:
                    raise osv.except_osv(u'错误!', u'供应商有重名!')
        res = super(res_partner, self).write(cr, uid, ids, vals, context)
        return res

    def _sale_order_count(self, cr, uid, ids, field_name, arg, context=None):
        res = dict(map(lambda x: (x, 0), ids))
        # The current user may not have access rights for sale orders
        order_obj = self.pool.get('sale.order')
        try:
            for partner in self.browse(cr, uid, ids, context):
                order_count = order_obj.search_count(cr, uid, [('partner_id', '=', partner.id),
                                                               ('real_so_id', '=', False),
                                                               ('state', '!=', 'cancel')], context=context)
                res[partner.id] = order_count + len([sale_order_obj.id for sale_order_obj in
                                                                                    partner.mapped('child_ids.sale_order_ids')])
        except:
            pass
        return res
    def compute_is_valid_for_order(self, cr, uid, ids, name, args, context=None):
        res = {}
        for partner in self.browse(cr, uid, ids, context=context):
            if partner.business_license and partner.licenses_for_opening_accounts:
                res[partner.id] = True
        return res


    def name_search(self, cr, uid, name, args=None, operator='ilike', context=None, limit=100):
        # 當搜索销售订单的时候进行 一系列操作 ，返回的符合条件的结果
        args = args or []
        if ['supplier', '=', True] in args:
            args.append(['is_valid_for_order', '=', True])
        super_list = super(res_partner, self).name_search(cr, uid, name, args,
                                                               operator=operator, context=context, limit=limit)
        return super_list
    def onchange_has_contract(self, cr, uid, ids, has_contract, context=None):
        if not has_contract:
            return {'value': {'contract_expired_date':False}}

    def _record_access_log(self, cr, uid, ids, name , args, context=None):
        res = {}
        not_have_sale_group = not self.pool['res.users'].has_group(cr, uid, 'base.group_sale_salesman')
        for res_partner_row in self.browse(cr, uid, ids, context=context):
            if not res_partner_row.supplier and not res_partner_row.employee and not_have_sale_group:
                self.pool.get("access.log").create(cr, uid, {'user_id': uid, 'access_model': self._name,
                                                             'context': "{'action_id':%s, 'seesion_id':%s}" %
                                                                        (context.get('params', {}).get('action'),
                                                                         request.session_id),
                                                             'record_id': res_partner_row.id},
                                                   context=context)
            res[res_partner_row.id] = res_partner_row.id
        return res

    def _compute_apply_delivery_link(self, cr, uid, ids, name, args, context=None):
        res = {}
        for id in ids:
            link = "%scard/exchange/%s" % (request_all.httprequest.url_root, id)
            res[id] = "<a href='%s'>%s</a>" % (link, link)
        return res

    _columns = {
        'principal': fields.many2one('customer.address', string=u'默认收货地址'),
        'requirement_type': fields.many2many('partner.requirement.type', 'requirement_type_rel', 'partner_id', 'requirement_type_id', string="需求类型"),
        'cust_grade': fields.selection([(u'VIP客户', u'VIP客户'), (u'重要客户', u'重要客户'), (u'正式客户', u'正式客户'),
                                        (u'定样客户', u'定样客户'), (u'潜力客户', u'潜力客户'), (u'跟进客户', u'跟进客户'), (u'中断客户', u'中断客户')],
                                       string="客户级别", select=True, track_visibility='onchange'),
        'corp_kind': fields.selection([(u'机关单位', u'机关单位'), (u'国有企业', u'国有企业'), (u'民营企业', u'民营企业'),
                                       (u'合资企业', u'合资企业'), (u'外资企业', u'外资企业'), (u'其它', u'其它')], string="企业类型", select=True),
        'industry_type': fields.selection([(u'政府机构', u'政府机构'), (u'文体教育', u'文体教育'), (u'医疗系统', u'医疗系统'), (u'金融系统', u'金融系统'), (u'电信行业', u'电信行业'), (u'汽车行业', u'汽车行业'), (u'石油化工', u'石油化工'),
                                           (u'服务行业', u'服务行业'), (u'电力系统', u'电力系统'), (u'行业协会', u'行业协会'), (u'部队系统', u'部队系统'), (u'制造工业', u'制造工业'), (u'交通运输', u'交通运输'), (u'市政工程', u'市政工程'), (u'房产物业', u'房产物业'), (u'科技信息', u'科技信息'), (u'农林渔业', u'农林渔业'), (u'其他', u'其他')], string="行业类别"),
        'cust_source': fields.char(u'来源'),
        'introducer': fields.char(u'介绍人'),
        'is_info_verify': fields.boolean(u'是否核实'),
        'share_to_uid': fields.many2one('res.users', string='共享给'),
        'last_contact_date': fields.datetime(u'最后跟进时间'),
        'cust_code': fields.char(u'客户编号'),
        'member_card': fields.char(u'会员卡'),
        'registered_capital': fields.integer(u'注册资金'),
        'invoice_type': fields.selection([(u'增值票(17%)', u'增值票(17%)'), (u'增值票(4%)', u'增值票(4%)'), (u'普通票', u'普通票'), (u'不限台头普票', u'不限台头普票'), (u'收据', u'收据')], string=u'发票类型'),
        'gender': fields.selection([(u'男', u'男'), (u'女', u'女')], string=u'性别'),
        'supplier_code': fields.char(u'供应商代码'),
        'supplier_grade': fields.char(u'供应商级别'),
        'supplier_payment_type': fields.char(u'付款类型'),
        'supplier_delivery_type': fields.char(u'送货方式'),
        'supplier_main_products': fields.char(u'主营产品'),
        'supplier_quality_analysis': fields.char(u'优劣分析'),
        'supplier_has_invoice': fields.boolean(u'是否含票'),
        'bank_name': fields.char(u'开户行'),
        'bank_account': fields.char(u'银行帐号'),
        'tax_no': fields.char(u'税号'),
        # 'contacts_name': fields.related('child_contacts_ids', 'contacts_id', type='char', string='联系人名字', domain=[('is_inauguratory', '=', True)]),
        'paid_amount': fields.function(_compute_customer_fee, string='已付金额', type='float'),
        'office_invoice': fields.function(_get_office_invoice_fee, string='纸质发票申请记录', type='float'),
        'QQ': fields.char('QQ'),
        'birthday': fields.date(u'生日'),
        'staff_number': fields.float(u'企业人数'),
        'user_id': fields.many2one('res.users', 'Salesperson', track_visibility='onchange'),
        'parent_id': fields.many2one('res.partner', 'Related Company', select=True, track_visibility='onchange'),
        'mobile': fields.char('Mobile', track_visibility='onchange'),
        # 'customer_address_contacts': fields.related('multi_address_ids', 'contacts', type="char", string="收货地址")
        'point_balance': fields.integer(u'积分余额'),
        'sale_order_count': fields.function(_sale_order_count, string='# of Sales Order', type='integer'),
        'contacts_email': fields.related('child_contacts_ids', 'email', relation='one2many', type='char', string='联系邮箱'),
        'is_auto_write_price': fields.boolean(u'是否自动写入价格'),
        'business_license': fields.binary(string='营业执照'),
        'licenses_for_opening_accounts': fields.binary(string='开户许可证'),
        'is_valid_for_order': fields.function(compute_is_valid_for_order, type='boolean', string='可以下单',
                                              store={'res.partner': (lambda self, cr, uid, ids, c={}: ids,
                                                     ['business_license', 'licenses_for_opening_accounts'], 20)}),
        'has_contract': fields.boolean(u'是否有合同'),
        'contract_expired_date': fields.date(u'合同到期时间'),
        'payment_method': fields.selection([(u'转账', u'转账'), (u'现金', u'现金'), (u'支票', u'支票'), (u'POS机', u'POS机')],
                                           string='付款方式'),
        'invoice_method': fields.selection([('manual', u'基于采购单明细(相当于预付款）'),
                                          ('picking', u'基于入库单（入库后付款）')], string='开票方式'),
        'record_access_log': fields.function(_record_access_log, u'记录访问人', type='char'),
        'apply_delivery_link': fields.function(_compute_apply_delivery_link, type='text', string='定制提货链接'),
        'stock_auto_note': fields.text('送货自动备注')
    }

    _defaults = {
        'is_auto_write_price': True,
    }


class customer_address(osv.osv):
    _inherit = 'customer.address'

    def name_search(self, cr, uid, name, args=None, operator='ilike', context=None, limit=100):
        # 當搜索销售订单的时候进行 一系列操作 ，返回的符合条件的结果
        args = args or []
        result_list = []
        super_list = super(customer_address, self).name_search(cr, uid, name, args,
                                                               operator=operator, context=context, limit=limit)
        if not super_list:
            result_list_id = self.pool.get('customer.address').search(cr, uid, ['|', ('contacts', 'ilike', name), '|', ('phone_number', 'ilike', name), '|', ('mobile_number', 'ilike', name), '|',
                                                                                ('street', 'ilike', name), ('partner_id', 'ilike', name)] + args, limit=limit, context=context or {})
            for customer_address_obj in self.browse(cr, uid, result_list_id, context=context or {}):
                result_list.append((customer_address_obj.id, customer_address_obj.contacts))
            return result_list
        return super_list
    _columns = {
        'sexual': fields.selection([(u'男', u'男'), (u'女', u'女')], string=u'性别'),
    }


class export_partner_contacts_wizard(osv.osv):
    _name = 'export.partner.contacts.wizard'

    def get_purchase_order_card_password(self, cr, uid, ids, context=None):
        contacts_obj = self.pool.get('company.contacts')
        if context is None:
            context = {}
        if isinstance(ids, int):
            this_id = ids
        else:
            this_id = ids[0]
        xls = StringIO.StringIO()
        xls_workbook = xlwt.Workbook(encoding="utf8")
        data_sheet = xls_workbook.add_sheet('data')
        if not context.get('default_exported_all_sale_contact'):
            partner_ids=context.get('active_ids')
        else:
            partner_ids=self.pool.get('res.partner').search(cr,uid,[],context=context)
        contacts_ids = contacts_obj.search(cr, uid, [('partner_id', 'in', partner_ids),
                                                     ('subscription_type', '=', u'快递')], context=context)
        #圆通模板格式
        field_names = ['', '', '', 'partner_id/user_id/name', '', '', '', '', '', 'partner_id/user_id/mobile', '', '',
                       '', '', 'contacts_id/name', 'mobile', 'partner_id/name', 'province_id', 'city_id', 'county_id',
                       'zip', 'street', '', '', '', '', '', '', '']
        header = [u'ID', u'始发地', u'运单号码', u'寄件人姓名', u'寄件单位', u'寄件地址', u'寄件省',
                  u'寄件市', u'寄件镇', u'寄件人联系电话', u'寄件人邮编', u'数量', u'寄件人签章', u'目的地名称'
            , u'收件人姓名', u'收件人联系电话', u'收件人单位名称', u'TO省', u'TO市（县）', u'TO区（镇）',
                  u'TO邮编', u'收件地址', u'内件品名', u'打印时间', u'备注', u'是否换单', u'物流订单号', u'创建时间', u'换单号']
        col_list = [3, 9, 14, 15,16, 17, 18, 19, 20, 21]
        constant_value = [u'上海', u'东方团购中心', u'上海市杨浦区国伟路135号']
        constant_list = [1, 4, 5]


        #申通模板格式
        field_names = ['', '', 'partner_id/user_id/name', '', 'partner_id/mobile', '', '', '',
                       '', '', 'contacts_id/name', '', 'mobile', 'province_id', 'city_id', 'county_id',
                       'street', 'zip', '', '', '', '', 'partner_id/cust_grade', '', '', '']
        header = [u'业务单号', u'寄件单位',
         u'寄件人姓名', u'寄件人电话', u'寄件人手机', u'寄件人省', u'寄件人市', u'寄件区 / 县', u'寄件人地址', u'寄件人邮编',
         u'收件人姓名', u'收件人电话', u'收件人手机', u'收件省', u'收件市', u'收件区 / 县', u'收件人地址', u'收件邮政编码',
         u'运费', u'订单金额', u'商品名称', u'商品编码', u'销售属性', u'商品金额', u'数量', u'备注']
        col_list = [2, 4, 10, 12, 13, 14, 15, 16, 17, 22]
        constant_value = [u'上海', u'上海市', u'东方团购中心', u'杨浦区国伟路135号10号楼']
        constant_list = [6, 7, 1, 8]

        length = len(header)
        for i in range(length):
            data_sheet.write(0, i, header[i])
        export_data = contacts_obj.export_data(
            cr, uid, contacts_ids, [field_names[name] for name in xrange(length) if field_names[name]],
            context=context).get('datas', [])
        row = 1
        for record in export_data:
            for locate in xrange(len(constant_list)):
                data_sheet.write(row, constant_list[locate], constant_value[locate])
            for i in range(len(record)):
                if record[i]:
                    export_value = str(record[i])  # 将数字转成字符串，以免被excel变成科学计数法
                    data_sheet.write(row, col_list[i], export_value)
            row += 1
        xls_workbook.save(xls)
        xls.seek(0)
        out = base64.encodestring(xls.getvalue())
        vals = {'data': out,
                'filename': u'deliery_export_%s.xls' % datetime.datetime.now().strftime("%Y%m%d"),
                'state': '2',
                }
        self.write(cr, uid, ids, vals, context=context)
        return {
            'type': 'ir.actions.act_window',
            'res_model': 'export.partner.contacts.wizard',
            'view_mode': 'form',
            'view_type': 'form',
            'res_id': this_id,
            'views': [(False, 'form')],
            'target': 'new',
        }

    _columns = {
        'exported': fields.integer(u'之前已导出', readonly=1),
        'filename': fields.char(u'文件名', readonly=1),
        'data': fields.binary(u'销售员联系人记录', readonly=1),
        'state': fields.boolean(string='状态')
    }
    _default = {
        'filename': u'要导出所有联系人列表',
        'state': False,
    }


class batch_set_partner_category(osv.osv_memory):
    _name = 'bath.set.partner.category'
    _columns = {
        'category_ids': fields.many2many('res.partner.category', 'bath_id', 'category_id', string='标签')
    }

    def bath_add_partner_category(self, cr, uid, ids, context=None):
        for add_category in self.browse(cr, uid, ids, context=context):
            self.pool.get('res.partner').write(cr, uid, context.get('active_ids'), {'category_id': [(4, category.id) for category in add_category.category_ids]}, context=context)
        return True

    def bath_delete_partner_category(self,cr, uid, ids, context=None):
        for add_category in self.browse(cr, uid, ids, context=context):
            self.pool.get('res.partner').write(cr, uid, context.get('active_ids'), {'category_id': [(3, category.id) for category in add_category.category_ids]}, context=context)
        return True

